using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using XUCore.Helpers;
using XUCore.WeChat;
using XUCore.WeChat.Helper;

namespace XUCore.WeChat.Enterprise
{
    public class EnterpriseWeChatWebSignature : IEnterpriseWeChatWebSignature
    {
        private readonly EnterpriseWeChatFuncs weChatFuncs;
        private readonly IEnterpriseWeChatTicketManager ticketManager;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="weChatFuncs"></param>
        /// <param name="ticketManager"></param>
        public EnterpriseWeChatWebSignature(EnterpriseWeChatFuncs weChatFuncs, IEnterpriseWeChatTicketManager ticketManager)
        {
            this.weChatFuncs = weChatFuncs;
            this.ticketManager = ticketManager;
        }
        /// <summary>
        /// 创建应用网页授权签名，对应agentConfig 和 wx.Config
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<EnterpriseWebSignatureResult> Create(EnterpriseWebSignatureRequest request)
        {
            var agentConfig = await CreateAgentSignature(request);
            var wxConfig = await CreateEnterpriseSignature(request);

            return new EnterpriseWebSignatureResult
            {
                WxConfig = wxConfig,
                AgentConfig = agentConfig
            };

        }
        /// <summary>
        /// 创建应用网页授权签名，对应agentConfig
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<EnterpriseWebSignatureResult.SignatureResult> CreateAgentSignature(EnterpriseWebSignatureRequest request)
        {
            (_, _, EnterpriseWeChatAgent agent) = weChatFuncs.GetEnterpriseWeChatAgentOptions(request.SuiteId, request.CorpId, request.AgentId);

            if (agent == null)
                throw new WeChatSdkException("应用id不存在，AgentId");

            var ticket = await ticketManager.GetAgentTicketAsync(request.SuiteId, request.CorpId, request.AgentId);

            var nonce = Str.GetNonceStr(16, isCharacter: false);

            var timestamp = DateTime.Now.ConvertToTimeStamp();

            var str = new StringBuilder();
            str.AppendFormat("jsapi_ticket={0}&", ticket);
            str.AppendFormat("noncestr={0}&", nonce);
            str.AppendFormat("timestamp={0}&", timestamp);
            str.AppendFormat("url={0}", request.Url);

            using var sha = SHA1.Create();
            var shaBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(str.ToString()));
            string sign = BitConverter.ToString(shaBytes).Replace("-", "").ToLower();

            return new EnterpriseWebSignatureResult.SignatureResult()
            {
                CorpId = request.CorpId,
                Nonce = nonce,
                TimeStamp = timestamp,
                Signature = sign,
                AgentId = agent.AgentId
            };
        }


        /// <summary>
        /// 创建企业网页授权签名，对应wx.Config
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<EnterpriseWebSignatureResult.SignatureResult> CreateEnterpriseSignature(EnterpriseWebSignatureRequest request)
        {
            (_, _, EnterpriseWeChatAgent agent) = weChatFuncs.GetEnterpriseWeChatAgentOptions(request.SuiteId, request.CorpId, request.AgentId);

            if (agent == null)
                throw new WeChatSdkException("应用id不存在，AgentId");

            var ticket = await ticketManager.GetEnterpriseTicketAsync(request.SuiteId, agent.CorpId, agent.AgentId);

            var nonce = Str.GetNonceStr(16, isCharacter: false);

            var timestamp = DateTime.Now.ConvertToTimeStamp();

            var str = new StringBuilder();
            str.AppendFormat("jsapi_ticket={0}&", ticket);
            str.AppendFormat("noncestr={0}&", nonce);
            str.AppendFormat("timestamp={0}&", timestamp);
            str.AppendFormat("url={0}", request.Url);

            using var sha = SHA1.Create();
            var shaBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(str.ToString()));
            string sign = BitConverter.ToString(shaBytes).Replace("-", "").ToLower();

            return new EnterpriseWebSignatureResult.SignatureResult()
            {
                CorpId = agent.CorpId,
                Nonce = nonce,
                TimeStamp = timestamp,
                Signature = sign,
                AgentId = agent.AgentId
            };
        }
    }



    /// <summary>
    /// 企业微信 H5的页面签名
    /// </summary>
    public class EnterpriseWebSignatureResult
    {
        /// <summary>
        /// 企业签名
        /// </summary>
        /// <value></value>
        public SignatureResult WxConfig { get; set; }
        /// <summary>
        /// 应用签名
        /// </summary>
        /// <value></value>
        public SignatureResult AgentConfig { get; set; }

        /// <summary>
        /// 分享数据参数
        /// </summary>
        public class SignatureResult
        {
            /// <summary>
            /// corpId
            /// </summary>
            public string CorpId { get; set; }
            /// <summary>
            /// 企业微信的应用id （e.g. 1000247）
            /// </summary>
            public int AgentId { get; set; }
            /// <summary>
            /// 随机数字
            /// </summary>
            public string Nonce { get; set; }
            /// <summary>
            /// 时间戳
            /// </summary>
            public long TimeStamp { get; set; }
            /// <summary>
            /// 签名
            /// </summary>
            public string Signature { get; set; }
        }
    }

    /// <summary>
    /// 请求签名参数
    /// </summary>
    public class EnterpriseWebSignatureRequest
    {
        /// <summary>
        /// 模板Id
        /// </summary>
        /// <value></value>
        public string SuiteId { get; set; }
        /// <summary>
        /// 企业id
        /// </summary>
        public string CorpId { get; set; }
        /// <summary>
        /// 企业微信应用id
        /// </summary>
        public int AgentId { get; set; }
        /// <summary>
        /// 当前需要签名的页面完整URL地址
        /// </summary>
        public string Url { get; set; }
    }
}